package io.gitee.zhangbinhub.admin.controller.api

import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.api.ServerApi
import io.gitee.zhangbinhub.admin.base.BaseController
import io.gitee.zhangbinhub.admin.constant.WorkFlowExpression
import io.gitee.zhangbinhub.admin.entity.WorkFlowDefinition
import io.gitee.zhangbinhub.admin.po.WorkFlowDefinitionPo
import io.gitee.zhangbinhub.admin.po.WorkFlowDefinitionQueryPo
import io.gitee.zhangbinhub.admin.service.WorkFlowDefinitionService
import io.gitee.zhangbinhub.admin.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.vo.InfoVo
import io.swagger.v3.oas.annotations.*
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import jakarta.validation.Valid
import jakarta.validation.constraints.NotEmpty
import jakarta.validation.constraints.NotNull
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

/**
 * @author zhang by 11/01/2019
 * @since JDK 11
 */
@Validated
@RestController
@RequestMapping("${ServerApi.basePath}${ServerApi.workFlow}")
@Tag(name = "工作流部署")
class WorkFlowDefinitionController @Autowired
constructor(
    logAdapter: LogAdapter,
    private val workFlowDefinitionService: WorkFlowDefinitionService
) : BaseController(logAdapter) {

    @Operation(summary = "新建工作流信息")
    @ApiResponses(ApiResponse(responseCode = "201", description = "创建成功"))
    @PreAuthorize(WorkFlowExpression.flowDefinition)
    @PutMapping(value = [ServerApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun create(@RequestBody @Valid workFlowDefinitionPo: WorkFlowDefinitionPo): ResponseEntity<WorkFlowDefinition> =
        workFlowDefinitionService.doCreate(workFlowDefinitionPo).let {
            ResponseEntity.status(HttpStatus.CREATED).body(it)
        }

    @Operation(summary = "删除指定的工作流信息")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；"))
    @PreAuthorize(WorkFlowExpression.flowDefinition)
    @DeleteMapping(value = [ServerApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun delete(
        @Parameter(description = "id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @RequestBody
        idList: MutableList<String>
    ): ResponseEntity<InfoVo> =
        workFlowDefinitionService.doDelete(idList).let {
            ResponseEntity.ok(InfoVo(message = "删除成功"))
        }

    @Operation(summary = "更新指定的工作流信息")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；配置ID不能为空；找不到信息；"))
    @PreAuthorize(WorkFlowExpression.flowDefinition)
    @PatchMapping(value = [ServerApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun update(@RequestBody @Valid workFlowDefinitionPo: WorkFlowDefinitionPo): ResponseEntity<WorkFlowDefinition> {
        if (CommonTools.isNullStr(workFlowDefinitionPo.id)) {
            throw WebException("ID不能为空")
        }
        return workFlowDefinitionService.doUpdate(workFlowDefinitionPo).let {
            ResponseEntity.ok(it)
        }
    }

    @Operation(summary = "查询工作流信息列表")
    @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过；"))
    @PreAuthorize(WorkFlowExpression.flowDefinition)
    @PostMapping(value = [ServerApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun query(@RequestBody @Valid workFlowDefinitionQueryPo: WorkFlowDefinitionQueryPo): ResponseEntity<CustomerQueryPageVo<WorkFlowDefinition>> =
        ResponseEntity.ok(workFlowDefinitionService.doQuery(workFlowDefinitionQueryPo))

    @Operation(summary = "部署工作流")
    @ApiResponses(ApiResponse(responseCode = "201", description = "部署成功"))
    @PreAuthorize(WorkFlowExpression.flowDefinition)
    @PutMapping(value = [ServerApi.definitionDeploy + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun deploy(@PathVariable(name = "id") id: String): ResponseEntity<WorkFlowDefinition> =
        ResponseEntity.status(HttpStatus.CREATED).body(workFlowDefinitionService.doDeploy(id))

    @Operation(summary = "流程定义文件下载")
    @ApiResponses(ApiResponse(responseCode = "200", description = "请求成功，进行文件下载；"))
    @GetMapping(value = [ServerApi.definition + "/file/{id}"], produces = [MediaType.ALL_VALUE])
    @Throws(WebException::class)
    fun downloadFile(
        request: HttpServletRequest, response: HttpServletResponse,
        @PathVariable(name = "id") id: String
    ) {
        workFlowDefinitionService.doDownLoadFile(request, response, id)
    }
}
